package com.fileopener;

import java.io.File;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.v4.content.FileProvider;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.appupdate.AppDownloadManager;
import com.appupdate.AppUpdateDialog;
import com.appupdate.Constants;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.stetho.common.StringUtil;
import com.huawei.android.hms.agent.HMSAgent;
import com.huawei.android.hms.agent.common.handler.ConnectHandler;
import com.huawei.android.hms.agent.push.handler.GetTokenHandler;
import com.xiaomi.mipush.sdk.MiPushClient;

import java.util.Map;
import java.util.HashMap;
import java.util.logging.Logger;

import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import static com.appupdate.Constants.downloadCancel;

public class FileOpener extends ReactContextBaseJavaModule implements LifecycleEventListener {

    private static ReactApplicationContext reactApplicationContext;
    private static final String TAG = "FileOpener";

    public FileOpener(ReactApplicationContext reactContext) {
        super(reactContext);
        reactContext.addLifecycleEventListener(this);
    }

    @Override
    public String getName() {
        return "FileOpener";
    }

    @Override
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        return constants;
    }

    AppUpdateDialog appUpdateDialog;
    AppDownloadManager mDownloadManager;

    @ReactMethod
    public void open(String fileArg, String contentType, String androidFileProviderName, Promise promise)
            throws JSONException {
        File file = new File(fileArg);

        if (file.exists()) {
            try {
                // Uri.fromFile was deprecated!!
                // Uri path = Uri.fromFile(file);
                Uri path = FileProvider.getUriForFile(getReactApplicationContext(), androidFileProviderName, file);
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(path, contentType);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                // Grant permission is very important!!
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                getReactApplicationContext().startActivity(intent);

                promise.resolve("Success!");
            } catch (android.content.ActivityNotFoundException e) {
                promise.reject("Error: No app can handle this request!");
            }
        } else {
            promise.reject("File not found!");
        }
    }

    @ReactMethod
    public void pushInit() {
        String brand = Build.BRAND.toLowerCase();
        switch (brand) {
            case "huawei":
            case "honor": {
                new PushHandler().initHuaWei();
                break;
            }
            case "xiaomi": {
                new PushHandler().initXm();
                break;
            }
            default: {
                String errDesc = "非华为小米手机请使用极光推送，手机品牌：" + brand;
                Toast.makeText(getCurrentActivity(), errDesc, Toast.LENGTH_SHORT).show();
                break;
            }
        }
    }

    @ReactMethod
    public void notifyJSDidLoad(Callback callback) {
        Log.d(TAG, "======");
        // send cached event
        if (getReactApplicationContext().hasActiveCatalystInstance()) {
            reactApplicationContext = getReactApplicationContext();
            WritableMap map = Arguments.createMap();
            map.putBoolean("inited", true);
            sendToClient("inited", map);
            callback.invoke(0);
        } else {
            callback.invoke(-1);
        }
    }


    @ReactMethod
    public void showUpdate(final String appName,String releaseNode,  final String url,boolean cancelable) {
        appUpdateDialog = new AppUpdateDialog();
        appUpdateDialog.showDialog(getCurrentActivity(), releaseNode,cancelable, new AppUpdateDialog.UpdateCallback() {
            @Override
            public void callback(int state) {
                if(state == Constants.DOWNLOAD_START) {
                    downloadAndInstall(url, appName);
                }else if(state == Constants.DIALOG_CLOSE){
                    downloadCancel = true;
                    if(mDownloadManager!=null) {
                        mDownloadManager.onPause();
                        mDownloadManager.cancel();
                    }
                }
            }
        });
    }

    private void downloadAndInstall(String url, String appName) {
        downloadCancel = false;
        String desc = "版本更新";
        mDownloadManager = new AppDownloadManager(getCurrentActivity(), new AppUpdateDialog.UpdateCallback() {
            @Override
            public void callback(int state) {
                mDownloadManager.onPause();
                appUpdateDialog.closeDialog();
            }
        });

        mDownloadManager.setUpdateListener(new AppDownloadManager.OnUpdateListener() {
            @Override
            public void update(int currentByte, int totalByte) {
                if (appUpdateDialog != null) {
                    appUpdateDialog.updateProgress(currentByte, totalByte);
                }
            }
        });

        mDownloadManager.downloadAndInstallApk(url, appName, desc);
    }

    /**
     * Native代码发送数据给react native
     * 当前注册的methodName包括
     * inited（Push初始化）、onToken （PushToken分配）
     * pushMsg（Push消息）、pushState（Push状体改变）
     * debug （调试消息）
     *
     * @param methodName
     * @param map
     */
    public static void sendToClient(String methodName, WritableMap map) {
        reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(methodName, map);
    }

    /**
     * Native代发发送消息给react native
     * 监听debug（调试消息）
     *
     * @param message
     */
    public static void sendToClient(String message) {
        WritableMap map = Arguments.createMap();
        map.putString("date", message);
        reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("debug", map);
    }


    @Override
    public void onHostResume() {

    }

    @Override
    public void onHostPause() {

    }

    @Override
    public void onHostDestroy() {
        reactApplicationContext = null;
    }

    @ReactMethod
    public void showMessage(String message){
        if(reactApplicationContext==null){
            return;
        }
        Toast.makeText(reactApplicationContext, message, Toast.LENGTH_SHORT).show();
    }

    @ReactMethod
    public void minimizeApp() {
        Intent startMain = new Intent(Intent.ACTION_MAIN);
        startMain.addCategory(Intent.CATEGORY_HOME);
        startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getReactApplicationContext().startActivity(startMain);
    }

    class PushHandler {

        private void initXm() {
            try {
                ApplicationInfo appInfo = reactApplicationContext.getPackageManager().getApplicationInfo(reactApplicationContext.getPackageName(),
                        PackageManager.GET_META_DATA);

                String appId = appInfo.metaData.getString("com.mi.appid");
                String appKey = appInfo.metaData.getString("com.mi.appkey");
//                String appId = "2882303761517685018";
//                String appKey = "5841768546018";
                if(TextUtils.isEmpty(appId) || TextUtils.isEmpty(appKey)){
                    showMessage("小米PUSH消息appID和appKey读取失败，请在Manifest里配置该信息");
                    return;
                }
                MiPushClient.registerPush(reactApplicationContext, appId, appKey);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
                sendToClient("小米推送获取Key失败" + e.getMessage());
            }

        }

        private void initHuaWei() {
            if (HMSAgent.init(getCurrentActivity())) {
                HMSAgent.connect(getCurrentActivity(), new ConnectHandler() {
                    @Override
                    public void onConnect(int rst) {
                        Logger.getLogger(this.getClass().getName()).info("HMS connect end:" + rst);

                        sendToClient("HMS connect end:" + rst);

                        if (rst != 0) {
                            JSONObject obj = new JSONObject();
                            try {
                                obj.put("retCode", rst);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });
            } else {
                sendToClient("华为pushInit失败");
            }

            getToken();
        }

        /**
         * 获取token
         */
        private void getToken() {
            // showLog("get token: begin");
            HMSAgent.Push.getToken(new GetTokenHandler() {
                @Override
                public void onResult(int rst) {
                    sendToClient("getToken-onResult" + rst);
                }

            });
        }
    }

}